/**
    @file dot_scene_loader.hpp
    @brief Ogre .scene loader
    @author jacmoe
    @note Adapted from http://www.ogre3d.org/tikiwiki/tiki-index.php?page=New+DotScene+Loader
*/
#ifndef DOT_SCENELOADER_H
#define DOT_SCENELOADER_H
 
// Includes
#include <OgreString.h>
#include <OgreVector3.h>
#include <OgreQuaternion.h>
#include <OgreMath.h>
#include <vector>

#include "interface.hpp"
#include "logger.hpp"
#include "util.hpp"
#include "portal_debug.hpp"
 
// Forward declarations
class TiXmlElement;

//! Additions to Ogre
namespace Ogre
{
	// Forward declarations
	class SceneManager;
	class SceneNode;
 
    /** @class nodeProperty
        @brief Class for node properties */
	class nodeProperty
	{
	public:
		String nodeName;
		String propertyNm;
		String valueName;
		String typeName;
 
		nodeProperty(const String &node, const String &propertyName, const String &value, const String &type)
			: nodeName(node), propertyNm(propertyName), valueName(value), typeName(type) {}
	};
 
    /** @class DotSceneLoader
        @brief A loader for Ogre .scene XML files */
	class DotSceneLoader
	{
	public:
		DotSceneLoader() : mSceneMgr(0) {}
		virtual ~DotSceneLoader() {}
 
		void parseDotScene(const String &SceneName, const String &groupName, PCZSceneManager *yourSceneMgr, PCZSceneNode *pAttachNode = NULL, const String &sPrependNode = "");
		String getProperty(const String &ndNm, const String &prop);
 
		std::vector<nodeProperty> nodeProperties;
		std::vector<String> staticObjects;
		std::vector<String> dynamicObjects;
 
	protected:
		void processScene(TiXmlElement *XMLRoot);
 
		void processNodes(TiXmlElement *XMLNode);
		void processExternals(TiXmlElement *XMLNode);
		void processEnvironment(TiXmlElement *XMLNode);
		void processTerrain(TiXmlElement *XMLNode);
		void processUserDataReference(TiXmlElement *XMLNode, PCZSceneNode *pParent = 0);
		void processUserDataReference(TiXmlElement *XMLNode, Entity *pEntity);
		void processOctree(TiXmlElement *XMLNode);
		void processLight(TiXmlElement *XMLNode, PCZSceneNode *pParent = 0);
		void processCamera(TiXmlElement *XMLNode, PCZSceneNode *pParent = 0);
 
		void processNode(TiXmlElement *XMLNode, PCZSceneNode *pParent = 0);
		void processLookTarget(TiXmlElement *XMLNode, PCZSceneNode *pParent);
		void processTrackTarget(TiXmlElement *XMLNode, PCZSceneNode *pParent);
		void processEntity(TiXmlElement *XMLNode, PCZSceneNode *pParent);
		void processParticleSystem(TiXmlElement *XMLNode, PCZSceneNode *pParent);
		void processBillboardSet(TiXmlElement *XMLNode, PCZSceneNode *pParent);
		void processPlane(TiXmlElement *XMLNode, PCZSceneNode *pParent);
 
		void processFog(TiXmlElement *XMLNode);
		void processSkyBox(TiXmlElement *XMLNode);
		void processSkyDome(TiXmlElement *XMLNode);
		void processSkyPlane(TiXmlElement *XMLNode);
		void processClipping(TiXmlElement *XMLNode);
 
		void processLightRange(TiXmlElement *XMLNode, Light *pLight);
		void processLightAttenuation(TiXmlElement *XMLNode, Light *pLight);
 
		String getAttrib(TiXmlElement *XMLNode, const String &parameter, const String &defaultValue = "");
		Real getAttribReal(TiXmlElement *XMLNode, const String &parameter, Real defaultValue = 0);
		bool getAttribBool(TiXmlElement *XMLNode, const String &parameter, bool defaultValue = false);

        /**
            @brief Adds all element attributes as node properties
            @param[in] name Reference to element name
            @param[in] XMLNode Pointer to the Xml element
            @author Sussch
        */
        void addElementProperties(const String &name, TiXmlElement *XMLNode);
 
		Vector3 parseVector3(TiXmlElement *XMLNode);
		Quaternion parseQuaternion(TiXmlElement *XMLNode);
		ColourValue parseColour(TiXmlElement *XMLNode);
 
 
		PCZSceneManager *mSceneMgr;
		PCZSceneNode *mAttachNode;
		String m_sGroupName;
		String m_sPrependNode;
	};
}
 
#endif // DOT_SCENELOADER_H

